package pl.edu.pw.perg.compinfodb.dbimport;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.CharBuffer;

import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;

import pl.edu.pw.perg.compinfodb.manager.IComplexElementManager;
import pl.edu.pw.perg.compinfodb.manager.IConnectorManager;
import pl.edu.pw.perg.compinfodb.manager.IElementTypeManager;
import pl.edu.pw.perg.compinfodb.manager.IFieldManager;
import pl.edu.pw.perg.compinfodb.manager.IHistoryManager;
import pl.edu.pw.perg.compinfodb.manager.IPhysicalElementManager;
import pl.edu.pw.perg.compinfodb.manager.IVirtualElementManager;
import pl.edu.pw.perg.compinfodb.xls.InvalidMetadataFormatException;
import pl.edu.pw.perg.compinfodb.xls.XLSMetadataReader;

public class DBImporter extends XLSMetadataReader {

	private static final double VERSION = 1.0;

	private IFieldManager fieldManager;
	private IElementTypeManager typeManager;
	private IVirtualElementManager virtualElementManager;
	private IPhysicalElementManager physicalElementManager;
	private IConnectorManager connectorManager;
	private IComplexElementManager complexElementManager;
	private IHistoryManager historyManager;

	public IHistoryManager getHistoryManager() {
		return historyManager;
	}

	public void setHistoryManager(IHistoryManager historyManager) {
		this.historyManager = historyManager;
	}

	public DBImporter() {
		String dbCtxPath = "classpath:pl/edu/pw/perg/compinfodb/dbimport/ctx/dbimport-context.xml";
		FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext(
				dbCtxPath);
		fieldManager = (IFieldManager) ctx.getBean("fieldManager");
		typeManager = (IElementTypeManager) ctx.getBean("typeManager");
		virtualElementManager = (IVirtualElementManager) ctx
				.getBean("virtualElementManager");
		physicalElementManager = (IPhysicalElementManager) ctx
				.getBean("physicalElementManager");
		connectorManager = (IConnectorManager) ctx.getBean("connectorManager");
		complexElementManager = (IComplexElementManager) ctx
				.getBean("complexElementManager");
		historyManager = (IHistoryManager) ctx.getBean("historyManager");
	}

	public static void main(String[] args) {

		if (args.length == 1) {
			String path = args[0];
			System.out.println(path);
			if (path.equals("-v")) {
				System.out.println("Version: " + VERSION);
				System.exit(0);
			}
			if (path.equals("test")) {
				XLSMetadataReader.setTest(true);
			}
		}

		DBImporter xls = new DBImporter();
		try {
			xls.removeDatabase();
			xls.createDatabase();
			System.out.println("All spreadsheets imported to database.");

		} catch (ArrayIndexOutOfBoundsException e) {
			System.err.println("Column index out of bounds: " + e.getMessage()
					+ ". Check properties file!\n");

			System.exit(1);
		} catch (Exception e) {
			System.err.println("Exception occured. Please report.");
			e.printStackTrace();
			System.exit(1);
		}

	}

	private void createDatabase() {

		fieldManager.saveAll(getFields());
		typeManager.saveAll(getTypes());
		typeManager.saveAll(connectInternally());
		virtualElementManager.saveAll(getElementsStructure());
		connectorManager.saveAll(getConnections());
		physicalElementManager.saveAll(getPhysicalElements());
		complexElementManager.saveAll(getComplexElements());

	}

	private void removeDatabase() {

		historyManager.deleteAll();
		complexElementManager.deleteAll();
		physicalElementManager.deleteAll();
		connectorManager.deleteAll();
		virtualElementManager.deleteAll();
		typeManager.deleteAll();
		fieldManager.deleteAll();

	}

	@Override
	protected void handleFormatError(InvalidMetadataFormatException e) {
		removeDatabase();
		System.out.println("Database not created.");
		throw e;
	}

	public void setFieldManager(IFieldManager fieldManager) {
		this.fieldManager = fieldManager;
	}

	public void setTypeManager(IElementTypeManager typeManager) {
		this.typeManager = typeManager;
	}

	public void setVirtualElementManager(
			IVirtualElementManager virtualElementManager) {
		this.virtualElementManager = virtualElementManager;
	}

	public void setPhysicalElementManager(
			IPhysicalElementManager physicalElementManager) {
		this.physicalElementManager = physicalElementManager;
	}

	public void setConnectorManager(IConnectorManager connectorManager) {
		this.connectorManager = connectorManager;
	}
}
